package com.hjm.common.push;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hjm.common.utils.request.DateUtils;
import com.hjm.framework.web.domain.AjaxResult;
import com.hjm.project.agentAysinfo.agentAysinfo.domain.AgentAysinfo;
import com.hjm.project.agentAysinfo.agentAysinfo.mapper.AgentAysinfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class AgentAsyncService {
    @Autowired
    private AgentAysinfoMapper agentAysinfoMapper;

    @Async
    public void executeAsyncTask(Map merMap) {
        try {
            String asyncStr = agentSupplementAsync(merMap);
            log.info("查询推送商户信息:"+merMap);
            log.info("推送机构数据信息："+asyncStr);
            String agentNum = merMap.get("AGENT_NO").toString();

            AgentAysinfo agentAysinfo = agentAysinfoMapper.selectAgentAysinfoByAgent(agentNum);
            if(agentAysinfo==null){
                log.info("【" + agentNum + "】" + "未配置推送信息,推送失败");
                return;
            }
            StringBuffer logStr=new StringBuffer();
            for (int i = 1;i <= 3;i++){
                String respStr= connectPostUrl(agentAysinfo.getAgentUrl(), asyncStr);
                log.info("给机构推送终端绑定结果报文-机构应答"+respStr);
                Map resp= JSONObject.parseObject(respStr);

                logStr.append("第" + i + "次推送结果："+respStr).append("\r\n");
                if(Integer.parseInt(resp.get("code").toString()) == 0){
                    log.info(logStr.toString());
                    return;
                }
                Thread.sleep(2000);
            }
        } catch (Exception e) {
            log.error("给代理商推送终端绑定结果异常：",e);
        }
    }


    public AjaxResult executeAsyncTaskBulu(Map merMap) {
        Map resp = null;
        try {
            String asyncStr = agentSupplementAsync(merMap);
            log.info("查询推送商户信息:" + merMap);
            log.info("推送机构数据信息：" + asyncStr);
            String agentNum = merMap.get("AGENT_NO").toString();

            AgentAysinfo agentAysinfo = agentAysinfoMapper.selectAgentAysinfoByAgent(agentNum);
            if (agentAysinfo == null) {
                return AjaxResult.error("【" + agentNum + "】" + "未配置推送信息");
            }
            String respStr = connectPostUrl(agentAysinfo.getAgentUrl(), asyncStr);
            log.info("给机构推送终端绑定结果报文-机构应答" + respStr);
            resp = JSONObject.parseObject(respStr);
            if (Integer.parseInt(resp.get("code").toString()) == 0) {
                return AjaxResult.success("推送成功");
            }
        } catch (Exception e) {
            log.error("给代理商推送终端绑定结果异常：", e);
            return AjaxResult.error("推送异常");
        }
        return AjaxResult.error(resp.get("msg").toString());
    }


    private String agentSupplementAsync(Map merMap) {
        Map asyncMap=new HashMap();
        asyncMap.put("idCard",merMap.get("SHOW_LEGALCERNO"));
        asyncMap.put("mobile",merMap.get("SHOW_LINKPHONE"));
        asyncMap.put("merchantSn",merMap.get("MERNO"));
        asyncMap.put("machineSn",merMap.get("machineNum"));
        asyncMap.put("realname",merMap.get("LEGAL_NAME"));
        asyncMap.put("createTime", DateUtils.getSysCurDateTime());
        asyncMap.put("merTb","7");
        return JSON.toJSONString(asyncMap);
    }


    public static String connectPostUrl(String url, String jsonParam) throws
            NoSuchAlgorithmException, KeyStoreException, ClientProtocolException, IOException, KeyManagementException {
        SSLConnectionSocketFactory sslsf = getSSLConnectionSocketFactory();
        CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        RequestConfig config = RequestConfig.custom().setSocketTimeout(40000).setConnectTimeout(10000).build();
        HttpPost httpPost = null;
        CloseableHttpResponse resp = null;
        try {
            httpPost = new HttpPost(url);
            httpPost.setConfig(config);
            StringEntity params = new StringEntity(jsonParam, "UTF-8");
            params.setContentType("application/json");
            httpPost.setEntity(params);
            resp = client.execute(httpPost);
            HttpEntity entity = resp.getEntity();
            String jsonString = EntityUtils.toString(entity, "UTF-8");

            if (resp.getStatusLine().getStatusCode() == 200)
                return jsonString;
        } catch (IOException e) {
            if ((e instanceof ConnectTimeoutException)) {
                throw new ConnectTimeoutException("connect timed out");
            }
            if ((e instanceof SocketTimeoutException)) {
                throw new SocketTimeoutException("Read timed out");
            }
            throw new IOException("IOException");
        } finally {
            if (resp != null) {
                try {
                    resp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpPost != null)
                httpPost.releaseConnection();
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (resp != null) {
            try {
                resp.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (httpPost != null)
            httpPost.releaseConnection();
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static SSLConnectionSocketFactory getSSLConnectionSocketFactory()
            throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        SSLContextBuilder context = new SSLContextBuilder().useProtocol("TLSv1.2");
        context.loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        });
        return new SSLConnectionSocketFactory(context.build());
    }
}
